package com.sr.security;

import com.sr.constant.Constant;
import com.sr.enums.ResponseCode;
import com.sr.exception.Assert;
import com.sr.pojo.SysPermission;
import com.sr.pojo.SysUser;
import com.sr.service.IPermissionService;
import com.sr.service.IUserService;
import com.sr.util.CacheUtil;
import com.sr.util.ToolUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author xiaochi
 * @date 2022/5/2 17:26
 * @desc UserDetailService
 */
@Component
@RequiredArgsConstructor(onConstructor = @__)
public class UserDetailService implements UserDetailsService {

    private final IUserService userService;
    private final IPermissionService permissionService;

    /**
     * 登录（方法由 JwtAuthenticationProvider 调用）
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUser user = CacheUtil.cache(Constant.User.BACK_USER_KEY+username,Constant.User.USER_KEY_EXPIRE,SysUser.class,() -> userService.getUserByUserName(username));
        Assert.assertNotNull(user,new UsernameNotFoundException(ResponseCode.SYSTEM_USERNAME_NOT_EXISTS.getMessage()));
        UserDetailVo userDetailVo = ToolUtil.copy(user, UserDetailVo.class);
        List<SysPermission> sysPermissions = CacheUtil.cache(Constant.User.BACK_USER_PERMISSION_KEY + username, Constant.User.USER_KEY_EXPIRE, SysPermission.class,() -> permissionService.permissionListByUserId(user.getId()));
        // 权限菜单
        userDetailVo.setMenus(permissionService.permissionTreeListMenuFilter(sysPermissions));
        // 前端按钮权限标识
        List<String> authBtnPerms  = sysPermissions.stream().filter(x -> !StringUtils.isEmpty(x.getCode())).map(SysPermission::getCode).distinct().collect(Collectors.toList());
        userDetailVo.setPermissions(authBtnPerms);

        String[] permsList = sysPermissions.stream().filter(x -> !StringUtils.isEmpty(x.getPerms())).map(SysPermission::getPerms).distinct().toArray(String[]::new);
        userDetailVo.setAuthorities(AuthorityUtils.createAuthorityList(permsList));
        return userDetailVo;
    }
}
